#ifndef __ACCEPTOR_HPP__
#define __ACCEPTOR_HPP__

/* Acceptor模块：这是用户态监听连接（类似于Connection）。是对监听连接进行管理的模块。 
    1. 通信套接字
    2. 对通信套接字上的事件监控进行管理的Channel
    3. LoopThread对应的EventLoop操作句柄
    5. 各种回调函数
*/

class Acceptor
{
    using AcceptedCallback = std::function<void(int)>;
private:
    Socket _sock;// 监听套接字
    EventLoop* _eventloop;// 监听连接对应的LoopThread对应的EventLoop句柄
    Channel _channel;// 对监听套接字进行事件监控的管理

    AcceptedCallback _accepted_cb;// 获取到新连接的回调函数
private:

    /**
     * @brief 创建监听套接字
     * 
     * @param port 监听的端口
     * @return int 创建好的套接字对应的文件描述符
     */
    int CreateServer(uint16_t port)
    {
#if SAFE_SOCKET
        Socket sock;
        assert(sock.CreateServer(port));

        _sock.Swap(sock);
#else
        assert(_sock.CreateServer(port));
#endif
        return _sock.Fd();
    }

    /* 读事件回调 */
    void HandleRead()
    {
        // 1. 获取新连接
        int sockfd = _sock.Accept();
        if(sockfd < 0)
        {
            ERR_LOG("accept new connection failed");
            return;
        }
        // 2. 调用连接到来的回调函数
        if(_accepted_cb) _accepted_cb(sockfd);
    }
public:
    Acceptor(EventLoop* eventloop, uint16_t port)
    : _sock(CreateServer(port)), _eventloop(eventloop), _channel(_sock.Fd(), _eventloop)
    {
        /* 设置读事件回调——有连接到来的回调函数 */
        _channel.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
    }

    /* 设置连接到来的回调函数 */
    void SetAcceptedCallback(const AcceptedCallback& cb)
    {
        _accepted_cb = cb;
    }

    /* 开始监听新连接 */
    void Listen()
    {
        _channel.EnableRead();
    }

    /* 获取监听套接字 */
    int Fd() const
    {
        return _sock.Fd();
    }
};

#endif